import { _decorator, Component, Node, Vec2, EventMouse, input, Input, UITransform, Label, Vec3, Sprite, Prefab, instantiate } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('TestLine')
export class TestLine extends Component {
    @property(Prefab)
    private dotPrefab: Prefab = null!; // 用于创建路径点的预制体

    @property(Node)
    private pointLabel: Node = null!; // 提示文本的Label节点

    @property(Number)
    private dotCount: number = 20; // 路径点数量

    @property(Number)
    private dotSpacing: number = 20; // 点之间的间距

    private startPoint: Vec2 | null = null; // 第一个点击位置
    private endPoint: Vec2 | null = null;   // 第二个点击位置
    private drawProgress: number = 0;    // 绘制进度 (0-1)
    private fadeProgress: number = 0;    // 消失进度 (0-1)
    private isDrawing: boolean = false;  // 是否正在绘制
    private isFading: boolean = false;   // 是否正在消失
    private drawSpeed: number = 0.2;     // 绘制速度 (秒)
    private fadeSpeed: number = 0.2;     // 消失速度 (秒)
    private fadeDelay: number = 0.1;     // 消失延迟时间 (秒)
    private fadeDelayTimer: number = 0;  // 消失延迟计时器
    private waveTime: number = 0;        // 波浪动画时间
    private waveSpeed: number = 50;      // 波浪移动速度

    private dots: Node[] = []; // 存储所有路径点

    start() {
        // 监听鼠标点击事件
        input.on(Input.EventType.MOUSE_DOWN, this.onMouseDown, this);
    }

    onMouseDown(event: EventMouse) {
        const mousePos = this.getMousePosition(event);

        if (!this.startPoint) {
            // 第一次点击，记录起始点
            this.startPoint = mousePos;
            this.showPointLabel(mousePos, "起点");
        } else {
            // 第二次点击，记录终点并开始动画
            this.endPoint = mousePos;
            this.showPointLabel(mousePos, "终点");
            this.startDrawingAnimation();
        }
    }

    private getMousePosition(event: EventMouse): Vec2 {
        const canvas = this.node.parent;
        const mousePos = event.getLocation();
        const worldPos = canvas.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(mousePos.x, mousePos.y, 0));
        return new Vec2(worldPos.x, worldPos.y);
    }

    private startDrawingAnimation() {
        this.clearDots(); // 清除现有的点
        this.createDots(); // 创建新的点
        this.drawProgress = 0;
        this.fadeProgress = 0;
        this.isDrawing = true;
        this.isFading = false;
        this.fadeDelayTimer = 0;
    }

    private clearDots() {
        // 清除所有现有的点
        this.dots.forEach(dot => dot.destroy());
        this.dots = [];
    }

    private createDots() {
        if (!this.startPoint || !this.endPoint || !this.dotPrefab) return;

        // 创建路径点
        for (let i = 0; i < this.dotCount; i++) {
            const dot = instantiate(this.dotPrefab);
            dot.parent = this.node;
            dot.active = false; // 初始时隐藏
            this.dots.push(dot);
        }
    }

    private updateDots(drawProgress: number, fadeProgress: number) {
        if (!this.startPoint || !this.endPoint) return;

        const dx = this.endPoint.x - this.startPoint.x;
        const dy = this.endPoint.y - this.startPoint.y;
        const distance = Math.sqrt(dx * dx + dy * dy);
        const baseAngle = Math.atan2(dy, dx) * 180 / Math.PI; // 基础角度（度数）

        // 计算可见点的数量
        const visibleCount = Math.floor(this.dotCount * drawProgress);
        const fadeCount = Math.floor(this.dotCount * fadeProgress);

        // 计算点之间的实际间距
        const spacing = distance / (this.dotCount - 1);

        for (let i = 0; i < this.dots.length; i++) {
            const dot = this.dots[i];
            
            // 判断点是否应该显示
            if (i >= fadeCount && i < visibleCount) {
                dot.active = true;

                // 计算点的位置
                const t = i / (this.dotCount - 1);
                const baseX = this.startPoint.x + dx * t;
                const baseY = this.startPoint.y + dy * t;

                // 添加波浪效果
                const wave = Math.sin(t * Math.PI * 4 + this.waveTime) * 20;
                const wave2 = Math.sin(t * Math.PI * 8 - this.waveTime * 0.5) * 10;
                const finalWave = wave + wave2;

                // 计算垂直偏移
                const perpX = Math.cos((baseAngle - 90) * Math.PI / 180) * finalWave;
                const perpY = Math.sin((baseAngle - 90) * Math.PI / 180) * finalWave;

                // 设置点的位置
                dot.setPosition(baseX + perpX, baseY + perpY);

                // 计算当前点的切线角度
                const nextT = Math.min(1, (i + 1) / (this.dotCount - 1));
                const prevT = Math.max(0, (i - 1) / (this.dotCount - 1));
                
                const nextX = this.startPoint.x + dx * nextT + Math.cos((baseAngle - 90) * Math.PI / 180) * Math.sin(nextT * Math.PI * 4 + this.waveTime) * 20;
                const nextY = this.startPoint.y + dy * nextT + Math.sin((baseAngle - 90) * Math.PI / 180) * Math.sin(nextT * Math.PI * 4 + this.waveTime) * 20;
                const prevX = this.startPoint.x + dx * prevT + Math.cos((baseAngle - 90) * Math.PI / 180) * Math.sin(prevT * Math.PI * 4 + this.waveTime) * 20;
                const prevY = this.startPoint.y + dy * prevT + Math.sin((baseAngle - 90) * Math.PI / 180) * Math.sin(prevT * Math.PI * 4 + this.waveTime) * 20;

                // 计算切线角度
                const tangentAngle = Math.atan2(nextY - prevY, nextX - prevX) * 180 / Math.PI;
                
                // 设置点的旋转
                dot.angle = tangentAngle;

                // 设置点的缩放以确保连接
                const sprite = dot.getComponent(Sprite);
                if (sprite) {
                    // 根据间距调整缩放
                    const scale = spacing / sprite.node.width;
                    dot.setScale(scale, scale);
                }
            } else {
                dot.active = false;
            }
        }
    }

    private showPointLabel(position: Vec2, text: string) {
        const label = this.pointLabel.getComponent(Label);
        if (label) {
            label.string = text;
            this.pointLabel.setPosition(position.x, position.y);
            this.pointLabel.active = true;
        }

        this.scheduleOnce(() => {
            this.pointLabel.active = false;
        }, 2);
    }

    update(deltaTime: number) {
        // 更新波浪时间
        this.waveTime += deltaTime * this.waveSpeed;

        if (this.startPoint && this.endPoint) {
            if (this.isDrawing) {
                this.drawProgress += deltaTime / this.drawSpeed;
                
                if (this.drawProgress >= 1) {
                    this.drawProgress = 1;
                    this.isDrawing = false;
                    this.fadeDelayTimer = 0;
                }
            } else if (!this.isFading) {
                this.fadeDelayTimer += deltaTime;
                if (this.fadeDelayTimer >= this.fadeDelay) {
                    this.isFading = true;
                }
            } else {
                this.fadeProgress += deltaTime / this.fadeSpeed;
                
                if (this.fadeProgress >= 1) {
                    this.fadeProgress = 1;
                    this.isFading = false;
                    this.startPoint = null;
                    this.endPoint = null;
                    this.clearDots();
                    return;
                }
            }

            this.updateDots(this.drawProgress, this.fadeProgress);
        }
    }
}